package com.kanesoft.android.gdx.actors.fight;

import com.badlogic.gdx.math.Vector2;
import com.kanesoft.android.gdx.actors.ActorObject;
import com.kanesoft.android.gdx.actors.ActorPhysicsParameters;
import com.kanesoft.android.gdx.control.WorldControl;
import com.kanesoft.android.gdx.widgets.GdxWidgets;
import com.kanesoft.android.gdx.widgets.sprites.SpriteWidget;

public abstract class FightActorObject extends ActorObject {

    private boolean isActorAttacking;

    private PowerFireballActor powerFireball;
    
    private FightActorStateMachine currentState;

    /* FIGHT STATES */
    protected FighterWaiting waitingState;
    protected FighterLose loseState;
    protected FighterWin winState;
    protected FighterWalkingForward walkingForwardState;
    protected FighterWalkingBackward walkingBackwardState;
    protected FighterPunching punchingState;
    protected FighterKicking kickingState;
    protected FighterJumping jumpingState;
    protected FighterFalling fallingState;
    protected FighterFallingPunch fallingPunchState;
    protected FighterFallingKick fallingKickState;
    protected FighterThrowFireball throwFireball;
    protected FighterFireballReleased fireballReleased;

    protected FighterHittenByPunch hittenByPunch;
    protected FighterHittenByKick hittenByKick;
    protected FighterHittenByFallingKick hittenByFallingKick;
    protected FighterHittenByFallingPunch hittenByFallingPunch;
    protected FighterHittenByPowerFireball hittenByPowerFireball;
    protected FighterHittenInTheAir hittenInTheAir;
    
    protected boolean isFightActive;
    
    public FightActorObject(int x, int y, float scaleObject, float scaleBitmap, WorldControl worldCtrl) {
        super(scaleObject, new ActorPhysicsParameters(0.5f*scaleObject, 0.9f*scaleObject, 240f*scaleObject*scaleObject, 5f*scaleObject, 6f*scaleObject, 2f*scaleObject), worldCtrl);
        
        Vector2 pixelPos = worldControl.convertWorldPointToPixel(x, y);
        
        actorSpriteWidget = new SpriteWidget(pixelPos.x, pixelPos.y, scaleBitmap, scaleBitmap, null, this);

        initializeMoviments();
        
        powerFireball = new PowerFireballActor(getActorBody().getPosition().x, getActorBody().getPosition().y,
                scaleBitmap, worldControl, this);

        setActorState(fallingState);
    }

    
    public FightActorObject(float scale, WorldControl worldCtrl) {
        super(scale, worldCtrl);
    }
    
    
    protected abstract void initializeMoviments();
    

    
    
    protected SpriteWidget actorSpriteWidget;
    private int lifePower = 100;
    

    public int getLifePower() {
        return lifePower;
    }
    
    public void decreseLifePower(int decreeseLevel) {
        
        lifePower -= decreeseLevel;
        if (lifePower < 0)  {
            lifePower = 0;
            notifyLifeIsGone();
        }
    }

    public void setActorState(FightActorStateMachine newState) {
        if (newState == null) return;
        
        if (currentState != null) {
            if (currentState.equals(newState)) return;
            if (currentState.OnLeave() == false) return;
        }

        if (newState.OnEnter() == false) return;

        System.out.println("setActorState(" + newState.getStateName() + ")");
        currentState = newState;
    }

    public FightActorStateMachine getActorState() {
        return currentState;
    }

    @Override
    public void updateActorPositions() {

        if (currentState == null) return;

        getSensorFixture().setFriction(0.2f);

        if (currentState.OnUpdate() == false) return;

        Vector2 objPosition = getActorBody().getPosition();

        float posX = objPosition.x - objectPhysicsParams.bodyWidth * actorScale;
        float posY = objPosition.y - (objectPhysicsParams.bodyHeight * actorScale * 1.5f);

        setPosition(worldControl.convertGLPosXToPixel(posX), worldControl.convertGLPosYToPixel(posY));

    }
    
    public void doActionWaiting() {
        setActorState(waitingState);
    }

    public void doActionWalkingForward() {
        setActorState(walkingForwardState);
    }

    public void doActionWalkingBackward() {
        setActorState(walkingBackwardState);
    }

    public void doActionPunch() {
        setActorState(punchingState);
    }

    public void doActionKick() {
        setActorState(kickingState);
    }

    public void doActionJump() {
        setActorState(jumpingState);
    }

    public void doActionThrowFireball() {
        if (powerFireball.canThrowFireball()) setActorState(throwFireball);
    }

    private void doActionCreateFireball() {
        float ballPosition = getActorBody().getPosition().x + 2;

        if (getHorizontalFlip()) {
            ballPosition = getActorBody().getPosition().x - 2;
        }
        powerFireball.throwFireball(ballPosition, getActorBody().getPosition().y);
    }

    @Override
    public GdxWidgets getActorWidget() {
        return actorSpriteWidget;
    }

    @Override
    public void setPosition(int x, int y) {
        actorSpriteWidget.setSpritePosition(x, y);
    }

    @Override
    public Vector2 getPosition() {
        return new Vector2(actorSpriteWidget.getPoxX(), actorSpriteWidget.getPoxY());
    }

    @Override
    public void setHorizontalFlip(boolean flip) {
        super.setHorizontalFlip(flip);
        actorSpriteWidget.setFlipSpriteHorizontal(flip);
    }
    
    public void startFight() {
        isFightActive = true;
    }
    
    public void pauseFight() {
        isFightActive = false;
    }


    @Override
    public void handleActorsCollision(ActorObject collidingActor) {
        if (collidingActor == null) return;
        if (collidingActor.isAttacking(this) == false) return;
        if (!(collidingActor instanceof FightActorObject)) return;
        FightActorObject OpponentFighter = (FightActorObject) collidingActor;

        if (OpponentFighter.getActorState() == null) return;
        
        

        isActorAttacking = false;

        if (getActorState().equals(jumpingState) || getActorState().equals(fallingState) || getActorState().equals(hittenInTheAir)
                || getActorState().equals(fallingKickState) || getActorState().equals(fallingPunchState)) {
            
            setActorState(hittenInTheAir);
            return;
        }

        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("Punching")) {
            setActorState(hittenByPunch);
            return;
        }

        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("Kicking")) {
            setActorState(hittenByKick);
            return;
        }

        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("FallingKick")) {
            setActorState(hittenByFallingKick);
            return;
        }

        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("FallingPunch")) {
            setActorState(hittenByFallingPunch);
            return;
        }

        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("FireballFlying")) {
            setActorState(hittenByPowerFireball);
            return;
        }
        
        if (OpponentFighter.getActorState().getStateName().equalsIgnoreCase("FireballExploding")) {
            setActorState(hittenByPowerFireball);
            return;
        } 

    }

    @Override
    public void onClick() {}

    @Override
    public void onAnimationComplete() {

        if (getActorState().getStateName().equalsIgnoreCase("ThrowFireball")) {
            doActionCreateFireball();
            setActorState(fireballReleased);
            return;
        }

        doActionWaiting();
    }

    @Override
    public boolean isAttacking(ActorObject attacked) {
        return isActorAttacking;
    }

    @Override
    public float getHitAceleration() {
        return 12;
    }

    @Override
    public void actualAttackBehavior(boolean attackBehavior) {
        isActorAttacking = attackBehavior;
    }

    @Override
    public void onSpriteOutOfScreen() {
        // TODO Auto-generated method stub

    }

    public void notifyLifeIsGone() {
        setActorState(loseState);
        
    }

}
